package com.happyface.andquiz.internals;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.InvalidObjectException;
import java.util.ArrayList;
import java.util.Random;

import android.app.Activity;
import android.util.Log;

public class Questions extends ArrayList<Question> {

    /**
     * the serial version UID
     */
    private static final long serialVersionUID = 1L;

    private Random randomGenerator;
    private String questionsFileName;
    private ArrayList<Integer> generatedIndexes;
    private int numberOfQuestions;
    private Activity activity;

    /**
     * Constructs a new Questions object
     * 
     * @param questionsFileName
     *            the name of the asset to open. This name can be hierarchical
     * @param activity
     *            the activity instantiating the object
     * 
     */
    public Questions(String questionsFile, Activity activity) {
	this.questionsFileName = questionsFile;
	this.generatedIndexes = new ArrayList<Integer>();
	this.randomGenerator = new Random();
	this.activity = activity;
    }

    /**
     * Gets the name of the file containing the questions
     * 
     * @return the file name
     */
    public String getQuestionsFileName() {
	return this.questionsFileName;
    }

    /**
     * Reads the file and loads the containing questions
     */
    public void load() {
	try {
	    InputStream inStream = activity.getAssets().open(
		    this.getQuestionsFileName());

	    if (inStream != null) {
		// prepare the file for reading
		InputStreamReader inputReader = new InputStreamReader(inStream);
		BufferedReader buffReader = new BufferedReader(inputReader);

		String line;

		String _questionText = null;
		String _optionA = null;
		String _optionB = null;
		String _optionC = null;
		String _optionD = null;

		int lineNumber = 0;
		// read every line of the file into the line-variable, on line
		// at the time
		while (true) {
		    line = buffReader.readLine();
		    // do something with the line
		    if (line != null) {
			lineNumber++;
			switch (lineNumber % 5) {
			case 1:
			    _questionText = line;
			    break;
			case 2:
			    _optionA = line;
			    break;
			case 3:
			    _optionB = line;
			    break;
			case 4:
			    _optionC = line;
			    break;
			case 0:
			    _optionD = line;
			    break;
			default:
			    break;
			}
			// reached end of file
		    } else {
			break;
		    }

		    if (lineNumber % 5 == 0) {
			Log.d("THEO", "New question added: " + _questionText
				+ " | " + _optionA + " | " + _optionB + " | "
				+ _optionC + " | " + _optionD);
			this.add(new Question(_questionText, _optionA,
				_optionB, _optionC, _optionD));
		    }
		}
	    }

	    this.numberOfQuestions = this.size();
	} catch (IOException e) {
	    Log.d("THEO", "I/O error occured: " + e.getLocalizedMessage());
	}
    }

    /**
     * Gets the question at the specified position in this list
     * 
     * @param index
     *            index of question to return
     * @return the question at the specified position
     */
    public Question getQuestion(int index) {
	if (index < 0 || index >= this.size()) {
	    throw new IndexOutOfBoundsException("The index is out of range");
	}
	return this.get(index);
    }

    /**
     * Gets a random question
     * 
     * @return the question, null if all questions depleted
     * @throws InvalidObjectException
     */
    public Question getRandomQuestion() throws InvalidObjectException {
	if (numberOfQuestions <= 0) {
	    throw new InvalidObjectException(
		    "No questions available to generate random");
	}

	int randomIndex = generateRandom();

	if (randomIndex != -1) {
	    return this.get(randomIndex);
	} else {
	    return null;
	}
    }

    /**
     * Generates a random number in a range without repeating
     * 
     * @return
     */
    private int generateRandom() {
	long range = numberOfQuestions;
	int randomNumber = (int) (range * randomGenerator.nextDouble());

	Integer genRandom = new Integer(randomNumber);
	if (!generatedIndexes.contains(genRandom)) {
	    generatedIndexes.add(genRandom);
	    Log.d("THEO", "Generated : " + randomNumber);
	    return randomNumber;
	} else {
	    if (generatedIndexes.size() != numberOfQuestions) {
		return generateRandom();
	    } else {
		return -1;
	    }
	}
    }
}
